package com.kylin.module.community.orm;

import com.kylin.hibernate.BaseHibernateDAO;
import com.kylin.module.user.orm.User;

import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

import java.util.Locale;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.criterion.Example;

import com.kylin.common.exception.BusinessException;
import com.kylin.common.exception.SystemException;

import com.kylin.common.paginate.Paging;
import com.kylin.common.util.MemObjFactory;
import com.kylin.module.community.forms.PostForm;

import com.kylin.common.dict.orm.Dict;

/**
 * Data access object (DAO) for domain model class Testcompany.
 * @see com.kylin.module.test.orm.Testcompany
 * @author liangzh
 */



public class PostDAO extends BaseHibernateDAO {

    private static final Log log = LogFactory.getLog(PostDAO.class);

    
    public boolean notComplexQuery(PostForm form){
    	if (form != null){
    		if ( (form.getMemberlanguage() == null || form.getMemberlanguage().equals(""))
    		  && (form.getCountry()==null || form.getCountry().equals(""))
    		  && (form.getInterestid() == null || form.getInterestid().intValue() ==0)
    		  && (form.getTargetlang() == null || form.getTargetlang().equals(""))
    		   && (form.getUsername() == null || form.getUsername().equals(""))
    		  ){
    			return true;
    		}else{
    			return false;
    		}
    		  
    	}else{
    		return true;
    	}
    	
    	
    }
    
	public Integer getTotal(User user, PostForm form, Locale loc){
        try {
            String queryString = null;
        	if (notComplexQuery(form)){
        		queryString = "select count(*) from Post p  " + buildCondition(user, form) ;
            }
            else{
            	queryString = "select count(*) from Post p , Member m" 
            		+ buildCondition(user, form) 
            		+ " and m.user = p.user";	
            }
        	
        	if (loc != null){
        		
        		queryString = queryString +  " and p.language = '" + loc + "'";
        	}
               
            Query query = getSession().createQuery(queryString);
            setParameters(user, query, form);
   		 	//query.setEntity(0, user);
            log.info("post quary total: "+ query.list().get(0));
   		 	return new Integer (query.list().get(0).toString());
         } catch (RuntimeException re) {
            log.error("get post total", re);
            throw re;
         }		
	}
    
	public List getList(User user, Integer limitstart, Integer limit, PostForm form, Locale loc){
        log.info("finding post " + limitstart + " " + limit );
        try {
        	String queryString = null;
        	if (notComplexQuery(form)){
        		queryString = " from Post p" + buildCondition(user, form);
        	}
        	else{
        		queryString = " from Post p, Member m " + buildCondition(user, form) 
        		+ " and m.user = p.user";
        	}
        	if (loc == null){
        		queryString = queryString + " order by  p.createdon desc";
        	}else{
        		queryString = queryString + " and p.language = '" + loc + "' order by  p.createdon desc";
        	}
           log.info(queryString);
           Query query = getSession().createQuery(queryString);
           setParameters(user, query, form);
           query.setFirstResult(limitstart.intValue());
           query.setMaxResults(limit.intValue());
           //log.info("size: "+ query.list().size());
           if (notComplexQuery(form)){
       		   		return query.list();
           }else{
        	   ArrayList list = new ArrayList();
        	   
        	   Iterator i = query.list().iterator();
        	   int n = 0;
        	   while(i.hasNext()){
        		   Object[] pair = (Object[])i.next();
        		   Post post = (Post)pair[0];		  
				   list.add(post);
				   n = n +1;
        	   }
        	   return list;
           }
        } catch (RuntimeException re) {
           log.error("query failed", re);
           throw re;
        }
		
	} 
	
	
	private String buildCondition(User user, PostForm form){
		String condition = " WHERE p.active = 1 ";
		if (form != null){
			if (form.getId() != null && form.getId().intValue() != 0){
				condition = condition + " and p.id = :id ";			
			}			
			if (form.getTagid() != null){
				condition = condition + " and p.tag = :tag ";			
			}
			if (form.getCatpostid() != null){
				condition = condition + " and p.catpost = :catpost ";			
			}
			if (!notComplexQuery(form)){
				if (form.getMemberlanguage() != null && !form.getMemberlanguage().equals("")){
					condition = condition + " and m.language = :memberlanguage ";			
				}
				if (form.getTargetlang() != null && !form.getTargetlang().equals("")){
					condition = condition + "  and m.targetlang = :targetlang ";			
				}
				if (form.getCountry() != null && !form.getCountry().equals("")){
					condition = condition + "  and m.country = :country ";			
				}
				if (form.getInterestid() != null && form.getInterestid().intValue() != 0){
					condition = condition + "  and m.interest = :interest ";			
				}			
				if (form.getUsername() != null && !form.getUsername().equals("")){
					condition = condition + " and p.user.username = :theusername ";			
				}
			}
			
		}
		if (user != null){
			condition = condition + " and p.user = :user ";			
		}			
		return condition;
		
	}

	private void setParameters(User user, Query query, PostForm form){
		String hql = query.getQueryString();
		log.info("hql: "+hql);
		try{
			if (hql.indexOf(":id") != -1) {	
				query.setParameter("id", form.getId());
			}			
			if (hql.indexOf(":user") != -1) {	
				query.setEntity("user", user);
			}
			if (hql.indexOf(":tag") != -1) {			
				Dict tag = (Dict)BaseHibernateDAO.findById(Dict.class, form.getTagid());
				query.setEntity("tag", tag);
			}
			if (hql.indexOf(":catpost") != -1) {			
				Dict catpost= (Dict)BaseHibernateDAO.findById(Dict.class, form.getCatpostid());
				query.setEntity("catpost", catpost);
			}			
			if (hql.indexOf(":memberlanguage") != -1) {			
				query.setParameter("memberlanguage", form.getMemberlanguage());
			}
			if (hql.indexOf(":targetlang") != -1) {			
				query.setParameter("targetlang", form.getTargetlang());
			}
			if (hql.indexOf(":country") != -1) {			
				query.setParameter("country", form.getCountry());
			}
			if (hql.indexOf(":interest") != -1) {
				Dict interest = (Dict)BaseHibernateDAO.findById(Dict.class, form.getInterestid());
				query.setParameter("interest", interest);
			}
			if (hql.indexOf(":memberlanguage") != -1) {			
				query.setParameter("memberlanguage", form.getMemberlanguage());
			}			
			if (hql.indexOf(":theusername") != -1) {			
				query.setParameter("theusername", form.getUsername());
			}			
		}
		catch(BusinessException be){
			log.info("exception in postdao setparameters() " + be.toString());
		}
		
	}	
	
/*	
	public Integer getTotal(User user){
        try {
            String queryString = "select count(*) from Post  where   active=1 and user = ? ";        	   
            Query query = getSession().createQuery(queryString);
   		 	query.setEntity(0, user);
            //log.info("postsize: "+ query.list().size());
   		 	return (Integer)query.list().get(0);
         } catch (RuntimeException re) {
            log.error("get post total", re);
            throw re;
         }		
	}
    
	public List getList(User user, Integer limitstart, Integer limit){
        log.info("finding post " + limitstart + " " + limit );
        try {
           String queryString = "from Post   where   active=1 and user = ? order by  createdon desc";        	   
           Query query = getSession().createQuery(queryString);
           query.setEntity(0, user);
           query.setFirstResult(limitstart);
           query.setMaxResults(limit);
  		 //query.setParameter(0, value);
           log.info("size: "+ query.list().size());
  		 return query.list();
        } catch (RuntimeException re) {
           log.error("find by property name failed", re);
           throw re;
        }
		
	}    
	*/
	
	/*
	public Paging show(User user, Integer limitstart, Integer limit){
		Paging page = new Paging();
		PostDAO fdao = new  PostDAO();
		
		page.setTotal(fdao.getTotal(user));
		page.setList(fdao.getList(user, limitstart, limit));
		page.setStart(limitstart);
		page.setLimit(limit);
		
		return page;		
	}		
	*/
//    
    public void save(Post transientInstance) {
        log.debug("Post instance");
        try{
        	super.save(transientInstance);
        }
        catch (BusinessException be){
        	
        }
    }
    
    public List list(User user) {
        log.info("finding post of " + user.getUsername() );
        try {
            String queryString = "from Post as f where  f.active=1 and f.user = ? order by f.createdon desc";
            Query query = getSession().createQuery(queryString);
            query.setEntity(0, user);
            query.setFirstResult(0);
            query.setMaxResults(10);
   		 	//query.setParameter(0, value);
            log.info("size: "+ query.list().size());
            for(int i =0 ; i < query.list().size(); i++){
            	Post post = (Post)query.list().get(i);
            	log.info(post.toString());
            }
            //log.info("sql: "+ query.getQueryString());
   		 	return query.list();
        }
        catch (RuntimeException re) {
           log.error("find by property name failed", re);
           throw re;
           
        }
  	}    
    
    public void add(User user, String content, Long pid){
  	   log.info("adding ");
  	   Post flist = new Post();
  	   
  	   flist.setUser(user);  	  
  	   flist.setFkppostid(pid);
  	   flist.setContent(content);
  	   //flist.setContent(content);
  	   flist.setCreatedon(new Date());
  	   flist.setActive(new Short("1"));
  	   flist.setHits(new Integer(0));	   
  	   
  	   try{
  		   super.save(flist);
  	   }
  	   catch(BusinessException be){
  		   log.info("adding friend"+be.toString());   
  	   }
     }        
    
	public void delete(Post persistentInstance) {
        log.debug("deleting Post instance");
        try{
	        super.delete(persistentInstance);
	    }
	    catch (BusinessException be){
	    }

    }
    
    public List findLast(Locale loc) {
        log.info("finding last 10 register");
        try {
           String queryString = "from Post as m where  m.active=1 and m.language = '" + loc + "' order by m.createdon desc";
           Query query = getSession().createQuery(queryString);
           query.setFirstResult(0);
           query.setMaxResults(10);
  		 //query.setParameter(0, value);
           log.info("size: "+ query.list().size());
  		 return query.list();
        } catch (RuntimeException re) {
           log.error("find by property name failed", re);
           throw re;
        }
  	}	
	
    public Post findById( java.lang.Long id) {
        log.debug("getting Post instance with id: " + id);
        try{
	        return (Post)findById(Post.class , id);
	    }
	    catch (BusinessException be){
	    	return null;
	    }
    }
    
    
    public List findByExample(Post instance) {
        log.debug("finding Post instance by example");
        try {
            List results = getSession()
                    .createCriteria("com.kylin.module.POST.orm.Post")
                    .add(Example.create(instance))
            .list();
            log.debug("find by example successful, result size: " + results.size());
            return results;
        } catch (RuntimeException re) {
            log.error("find by example failed", re);
            throw re;
        }
    }    
    
    public List findByProperty(String propertyName, Object value) {
      log.debug("finding Post instance with property: " + propertyName
            + ", value: " + value);
      try {
         String queryString = "from Post as model where model." 
         						+ propertyName + "= ?";
         Query queryObject = getSession().createQuery(queryString);
		 queryObject.setParameter(0, value);
		 return queryObject.list();
      } catch (RuntimeException re) {
         log.error("find by property name failed", re);
         throw re;
      }
	}

    public Post merge(Post detachedInstance) {
        log.debug("merging Post instance");
        try {
            Post result = (Post) getSession()
                    .merge(detachedInstance);
            log.debug("merge successful");
            return result;
        } catch (RuntimeException re) {
            log.error("merge failed", re);
            throw re;
        }
    }

    public void attachDirty(Post instance) {
        log.debug("attaching dirty Post instance");
        try {
            getSession().saveOrUpdate(instance);
            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }
    
    public void attachClean(Post instance) {
        log.debug("attaching clean Post instance");
        try {
            getSession().lock(instance, LockMode.NONE);
            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }
}